package day0306;

public class MyDBLink {

    private Node first;

    private Node last;

    private int size;

    public void add(Object element) {
        Node node = new Node(last, element, null);
        if (last == null) {
            // 没有元素
            first = node;
        } else {
            last.next = node;
        }
        last = node;
        size ++;
    }

    /**
     * 根据下标删除元素
     * @param index
     * @return
     */
    public Object remove(int index){
        // TODO(index 合法性)
        Node node = getNode(index);
        remove(node);
        return node.value;
    }

    /**
     * 删除指定元素
     * @param element
     * @return
     */
    public boolean remove(Object element){
        // TODO(index 合法性)
        Node node = first;

        for (int i = 0; i < size; i++) {
            if (node.value.equals(element)){
                break;
            } else {
                node = node.next;
            }
        }

        remove(node);

        return true;

    }


    /**
     * 在链表删除某个节点
     * @param node
     */
    private void remove(Node node){
        if (first == last) {
            first = null;
            last = null;
        }

        if (node == first) {
            first.next.pre = null;
            first = first.next;
        } else if (node == last) {
            last.pre.next = null;
            last = last.pre;
        } else {
            node.pre.next = node.next;
            node.next.pre = node.pre;
        }

        node.pre = null;
        node.next = null;
    }


    /**
     * 根据下标找 Node 节点
     * @param index
     * @return
     */
    private Node getNode(int index){
        // TODO(index 合法性)
        Node node;
        if (index < size / 2){
            node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        } else {
            node = last;
            for (int i = 0; i < size - index; i++) {
                node = node.pre;
            }
        }
        return node;
    }


    public Object get(int index) {
        return getNode(index).value;
    }

    public int size() {
        return this.size;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("MyDBLink[");
        Node node = first;

        while (node != null) {
            sb.append(node.value + ", ");
            node = node.next;
        }
        return sb.substring(0, sb.length() - 2) + "]";
    }

    private class Node {
        private Object value;

        private Node pre;

        private Node next;


        public Node(Node pre, Object value, Node next) {
            this.pre = pre;
            this.value = value;
            this.next = next;
        }
    }
}
